import { _decorator, AssetManager, Component, instantiate, Node, Prefab } from 'cc';
import { UIPanel } from './Panel/UIPanel';
const { ccclass } = _decorator;

@ccclass('UIManager')
export class UIManager extends Component {
    private static _Instance: UIManager;
    public static get Instance(): UIManager { return UIManager._Instance; }
    /**界面字典 */
    private panels: Map<string, UIPanel> = new Map<string, UIPanel>();

    public onLoad(): void {
        UIManager._Instance = this;
    }

    public start(): void {
        // 将本地的界面添加到字典中
        for (let i = 0, count = this.node.children.length; i < count; i++) {
            let layer = this.node.children[i];
            for (let j = 0, jcount = layer.children.length; j < jcount; j++) {
                let panel = layer.children[j].getComponent(UIPanel);
                if (panel) {
                    this.panels.set(panel.name, panel);
                    panel.panelName = panel.name;
                    if (panel.node.active) {
                        panel.OnInit();
                        panel.OnShow();
                    }
                }
            }
        }
    }

    /**
     * 异步打开界面（用于打开处于bundle包中的界面）
     * @param bundle 包名
     * @param path 相对路径
     * @param data 数据
     */
    public Open(bundle: string, path: string, data?: any, callback?: Function, caller?: any) {
        let panelName = `${bundle}/${path}`;
        if (this.panels.has(panelName)) {
            let panel = this.panels.get(panelName);
            panel.Show(data);
            callback?.call(caller, panel);
        } else {
            let b: AssetManager.Bundle = AssetManager.instance.getBundle(bundle);
            if (!b) {
                AssetManager.instance.loadBundle(bundle, () => {
                    this.Open(bundle, path, data, callback, caller);
                })
            } else {
                b.load(path, Prefab, (err, asset: Prefab) => {
                    if (!err) {
                        let panel = instantiate(asset).getComponent(UIPanel);
                        panel.node.setParent(this.node.children[panel.layer]);
                        panel.OnInit(data);
                        panel.Show(data);
                        panel.panelName = panelName;
                        callback?.call(caller, panel);
                        this.panels.set(panelName, panel);
                    } else {
                        console.error(err);
                    }
                });
            }
        }
    }

    /**
     * 同步打开界面
     * @param name 界面名称
     * @param data 数据
     */
    public OpenSync(name: string, data?: any) {
        if (this.panels.has(name)) {
            let panel = this.panels.get(name);
            panel.Show(data);
        }
    }

    /**
     * 隐藏界面
     * @param panelName 界面名
     */
    public Hide(panelName: string) {
        if (this.panels.has(panelName)) {
            let panel = this.panels.get(panelName);
            panel.node.active = false;
            panel.OnHide();
        }
    }

    /**
     * 销毁界面
     * @param panelName 界面名
     */
    public Destroy(panelName: string) {
        if (this.panels.has(panelName)) {
            let panel = this.panels.get(panelName);
            this.panels.delete(panelName);
            panel.OnDestroy();
            panel.node.destroy();
        }
    }
}


